package com.kensure.shike.weixinpay.utils;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.io.Writer;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.io.xml.PrettyPrintWriter;
import com.thoughtworks.xstream.io.xml.XppDriver;

public class XmlUtil {
	public static Map<String, Object> parseXML(HttpServletRequest request) throws IOException, DocumentException {
		Map<String, Object> map = new HashMap<String, Object>();
		/* 通过IO获得Document */
		SAXReader reader = new SAXReader();
		Document doc = reader.read(request.getInputStream());
		// 得到xml的根节点
		Element root = doc.getRootElement();
		recursiveParseXML(root, map);
		return map;
	}

	private static void recursiveParseXML(Element root, Map<String, Object> map) {
		// 得到根节点的子节点列表
		List<Element> elementList = root.elements();
		// 判断有没有子元素列表
		if (elementList.size() == 0) {
			map.put(root.getName(), root.getTextTrim());
		} else {
			// 遍历
			for (Element e : elementList) {
				recursiveParseXML(e, map);
			}
		}
	}

	/**
	 * 微信回调参数解析
	 *
	 * @param request
	 * @return
	 */
	public static String getPostStr(HttpServletRequest request) {
		StringBuffer sb = new StringBuffer();
		try {
			InputStream is = request.getInputStream();
			InputStreamReader isr = new InputStreamReader(is, "UTF-8");
			BufferedReader br = new BufferedReader(isr);
			String s = "";
			while ((s = br.readLine()) != null) {
				sb.append(s);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		String xml = sb.toString(); // 次即为接收到微信端发送过来的xml数据
		return xml;
	}

	/**
	 * XML格式字符串转换为Map
	 *
	 * @param strXML
	 *            XML字符串
	 * @return XML数据转换后的Map
	 * @throws Exception
	 */
	public static Map<String, String> xmlToMap(String strXML) {
		Map<String, String> data = new HashMap<String, String>();
		try {
			DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
			DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
			InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
			org.w3c.dom.Document doc = documentBuilder.parse(stream);
			doc.getDocumentElement().normalize();
			NodeList nodeList = doc.getDocumentElement().getChildNodes();
			for (int idx = 0; idx < nodeList.getLength(); ++idx) {
				Node node = nodeList.item(idx);
				if (node.getNodeType() == Node.ELEMENT_NODE) {
					org.w3c.dom.Element element = (org.w3c.dom.Element) node;
					data.put(element.getNodeName(), element.getTextContent());
				}
			}
			stream.close();
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return data;
	}

	private static XStream xstream = new XStream(new XppDriver() {
		public HierarchicalStreamWriter createWriter(Writer out) {
			return new PrettyPrintWriter(out) {
				// 对所有xml节点都增加CDATA标记
				boolean cdata = true;

				public void startNode(String name, Class clazz) {
					super.startNode(name, clazz);
				}

				protected void writeText(QuickWriter writer, String text) {
					if (cdata) {
						writer.write(text);
					} else {
						writer.write(text);
					}
				}
			};
		}
	});

	public static String messageToXML(Serializable paymentPo) {
		xstream.alias("xml", paymentPo.getClass());
		return xstream.toXML(paymentPo);
	}
}